<?php

namespace App\Services\Scenic\Driver;

use App\Models\Scenic\ScenicSpot;
use App\Models\Scenic\ScenicSpotGoodsPrice;
use App\Models\Scenic\ScenicSpotIntroduce;
use App\Models\Scenic\ScenicSpotProvider;
use App\Services\Scenic\ScenicServiceTools;
use App\Services\Scenic\TuNiuScenicService;
use App\Trip\Enums\Scenic\ScenicProvider;
use App\Trip\Geo\Amap\POI;
use App\Trip\Geo\Location;
use Illuminate\Support\Facades\Redis;

class LocalScenicProvider implements ScenicProviderInterface
{

    /**
     * 获取列表
     * @param string $keyword
     * @param int $page
     * @param int $pageSize
     * @param array $sort
     * @param Location $locationData
     * @return array
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function list(string $keyword,int $page,int $pageSize,array $sort,Location $locationData) :array
    {
        //todo db处理
        $resp = [
            'scenic_spots' => [],
            'total' => 0,
            'current_page' => $page,
            'last_page' => 0,
        ];
        return $resp;
    }

    /**
     * 推荐景点
     * @param int $limit
     * @param Location $locationData
     * @return array
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function recommend(int $limit,Location $locationData):array
    {
        $geo = new POI();
        $types = [
            '050000',
            '060000',
            '070000',
            '090000',
            '100000',
            '110000',
            '150105',
            '150203',
            '190100',
            '190300',
            '190400',
            '120000',
        ];
        $res = $geo->around($locationData, implode('|', $types));
        $ret = $res[0] ?? [];
        if (empty($ret)) {
            throw new \Exception(404, '定位信息错误');
        }
        $cacheKey = sprintf(config("trip.scenic.scenic_sale_key"), $ret['citycode']);
        $scenicIds = Redis::zrevrange($cacheKey, 0, ($limit - 1), 'withscores');
        if (empty($scenicIds)) {
            return [];
        }
        $spotIntroduces = ScenicSpotIntroduce::whereIn('scenic_id', $scenicIds)->get();
        $spotIntroduceMap = [];
        foreach ($spotIntroduces as $spotIntroduce) {
            $spotIntroduceMap[$spotIntroduce->scenic_id] = $spotIntroduce->introduce;
        }
        $spots = ScenicSpot::whereIn('scenic_id', $scenicIds)->get();
        $data = [];
        foreach ($spots as $spot) {
            $minPrice = ScenicSpotGoodsPrice::where('scenic_id', $spot->scenic_id)
                ->min('sale_price');
            $distance = $locationData->getDistance(new Location($spot->location));
            $data[] = [
                'scenic_name' => $spot->scenic_name,
                'scenic_id' => $spot->scenic_id,
                'price' => $minPrice ?? 0,
                'rating' => 10,
                'image' => $spot->image,
                'distance' => $distance,
                'scenic_class' => ScenicServiceTools::getScenicClass($spot->scenic_name),
                'description' => $spotIntroduceMap[$spot->scenic_id] ?? '',
            ];
        }
        return $data;
    }

    /**
     * @param int $limit
     * @param Location $locationData
     * @return array
     * @throws \Exception
     */
    public function popular(int $limit,Location $locationData):array
    {
        //todo 人气暂时和推荐一样
        return $this->recommend($limit,$locationData);
    }

    /**
     * 景点搜索
     * @param string $keyword
     * @param string $citycode
     * @param string $inputLocation
     * @return array
     */
    public function search(string $keyword, string $citycode, string $inputLocation): array
    {
        // TODO: Implement search() method.
        return [];
    }

    public function detail(string $id,Location $inputLocation) :array
    {
        // TODO: Implement detail() method.
        return [];
    }

    public function tickets(string $scenicId): array
    {
        // TODO: Implement tickets() method.
        return [];
    }

    public function ticket(string $ticketId): array
    {
        // TODO: Implement ticket() method.
        return [];
    }

    public function ticketToDb($scenicId,$productId) :bool
    {
        return true;
    }

}
